Proyecto - Contingencias de Vida II

Librerías e importaciones

source("cod/setup.R")
source("cod/load_database.R")
source("cod/prob_estim.R")

Factor de degradación para estados CAR

La metodología original empezaba a dar problemas con probabilidades negativas a partir de una edad aproximada de 95 años, por lo que se decidió implementar un factor de reducción desde los 90 años para primero, complementar la probabilidad creciente de muerte y además poder arreglar el problema de probabilidades negativas.

Construir las tablas

source("cod/tablas.R")
Males <- tablas(1)
Females <- tablas(2)

Mejora de mortalidades en el tiempo y mejora de transiciones de empeoramiento

source("cod/degradar_mort.R")
source("cod/calculo_anualidades.R")
edad20 <- degradar_mort(20, 1)

Comprobación de mejoras

calculo_acumulado(20, edad20)
##          Able     Mild Moderate   Severe Profound     Dead
## [1,] 47.37206 6.189601 3.146575 2.593122 3.690927 37.00772
edad20sin_m <- lapply(Males, function(x) as.data.frame(x[21:120,]))
calculo_acumulado(20, edad20sin_m)
##          Able     Mild Moderate   Severe Profound     Dead
## [1,] 42.42812 5.499605 2.619834 1.856993 2.063667 45.53178

Hay una clara diferencia entre mejorías de mortalidades

Cálculo de valores presentes

Se puede realizar varios seguros con los resultados de calculo_vp. Nótese que estamos en edad 20

prueba <- calculo_vp(20, edad20, 0.07, 0.03)

# Seguro de vida normal, 100 millones
(prueba[6]*100e6 )/(12*prueba[1])
## [1] 40566.67
# Seguro de vida con anualidades en caso de Severe o Profound, pagando Mild y Moderate
(prueba[6]*100e6 + 12*(1.5e6*prueba[4] + 3e6*prueba[5]))/(12*(prueba[1]+prueba[2]+prueba[3]))
## [1] 131244.9
# Seguro de vida con anualidades pagando 0.25e6 en aumento de estado
(prueba[6]*100e6 + 12*(0.25e6*prueba[2] +
                         0.5e6*prueba[3] +
                         0.75e6*prueba[4] +
                         1e6*prueba[5]))/(12*prueba[1])
## [1] 111971.3
# Seguro de vida con anualidades pagando 0.5e6 en aumento de estado
(prueba[6]*100e6 + 12*(0.5e6*prueba[2] +
                         1e6*prueba[3] +
                         1.5e6*prueba[4] +
                         2e6*prueba[5]))/(12*prueba[1])
## [1] 183375.8

Cálculo de las primas

source("cod/prima.R")
# primas_h <- sapply(20:70, function(x) prima(calculo_vp(x, degradar_mort(x, 1), 0.05, 0.03)))
# primas_m <- sapply(20:70, function(x) prima(calculo_vp(x, degradar_mort(x, 2), 0.05, 0.03)))
# df_primas <- data.frame(x = 20:70, hombres = primas_h, mujeres = primas_m)
# write_xlsx(df_primas, "res/primas.xlsx")
df_primas <- read_xlsx("res/primas.xlsx")

Portafolio

Generación del portafolio

Se utiliza una normal para centrar las observaciones en una edad de interés

set.seed(70707)
portfolio <- data.frame(edad = round(rnorm(5000, mean = 45, sd = 6.5)),
                         sexo = round(runif(5000, 1, 2))) %>% 
  arrange(., edad, sexo) %>%
  mutate(id = dense_rank(paste(edad, sexo)))
descripcion <- portfolio %>% count(edad, sexo)

Y se genera la lista de probabilidades

lista <- list()
for(i in 1:length(descripcion$edad)) {
  prob_matrices <- degradar_mort(descripcion$edad[i], descripcion$sexo[i])
  
  # Se acumulan las probabilidades previo a la simulación estocástica
  lista[[i]] <- lapply(prob_matrices, function(df) {
    t(apply(df[, 2:7], 1, cumsum))
  })
}

Representación del portafolio

Prima nivelada

prima_n <- function(interes, inflacion){
  primas_p <- sapply(1:length(descripcion$edad),
                   function(x) calculo_vp(descripcion$edad[x],
                                          degradar_mort(descripcion$edad[x],
                                                        descripcion$sexo[x]),
                                          interes, inflacion))
  nivelada <- primas_p %*% descripcion$n
  return(prima(nivelada))
}
(nivelada <- prima_n(0.05, 0.03))
## [1] 266612.7

Análisis de sensibilidad

# names <- paste(as.character(3:7), "%", sep = "")
# tabla <- sapply(3:7/100,  function(x) sapply(3:7/100, function(y) prima_n(x, y)))
# tabla <- data.frame(tabla, row.names = names)
# colnames(tabla) <- names
# write_xlsx(tabla, "res/sensibilidad.xlsx")
tabla <- read_xlsx("res/sensibilidad.xlsx")
tabla
## # A tibble: 5 × 5
##      `3%`    `4%`    `5%`    `6%`    `7%`
##     <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
## 1 389725. 321474. 266613. 222588. 187272.
## 2 473480. 389725. 322062. 267558. 223727.
## 3 574562. 472596. 389725. 322640. 268489.
## 4 695523. 572439. 471731. 389725. 323209.
## 5 839001. 691731. 570364. 470883. 389725.

Modelo estocástico

Proyección de primas

Esto es extra, no se piden.

source("cod/proy_prima.R")
# set.seed(70707)
# t <- proc.time()
# proy_prima_data <- proy_prima_par(10000, 0.05, 0.03)
# raw <- proy_prima_data
# proc.time()-t

Calculamos la prima estocástica al percentil 99.5

# proy_prima_data <- list()
# for(i in 1:10000){
#   proy_prima_data[[i]] <- raw[,,i]
# }
# proy_prima_data <- sapply(proy_prima_data, function(x) prima(descripcion$n %*% x))
# write_xlsx(data.frame(proy_prima_data), "res/proy_prima.xlsx")
proy_prima_data <- read_xlsx("res/proy_prima.xlsx")
quantile(proy_prima_data[[1]], 0.005)
##   0.5% 
## 142196

Preparación para modelar estocásticamente

Variables globales

interes <- 0.07
inflacion <- 0.03
edades <- portfolio$edad
rango <- 120 - min(edades)
v <- (1 + inflacion) / (1 + interes)
v_power <- v^(0:rango)
mujeres <- sum(portfolio$sexo == 2)
hombres <- sum(portfolio$sexo == 1)
sexos <- portfolio$sexo == 1
variables <- c("lista",
                "portfolio",
                "sexos",
                "hombres",
                "mujeres",
                "rango",
                "v_power",
                "proyeccion") 

Funciones

source("cod/proyecciones.R")

Proyeccion grupal de pagos y vivos

Única

set.seed(1)
t <- proc.time()
prueba <- proyeccion()
proc.time()-t
##    user  system elapsed 
##    1.69    0.00    1.83

Paralelizado

# t <- proc.time()
# proyeccion_data <- proyeccion_par(100, cores = 2)
# proc.time()-t

Resumen estocástico

Esperanza

source("cod/resumen_estoc.R")
# t <- proc.time()
# media <- esperanza(proyeccion_data)
# proc.time()-t

Percentil

# t <- proc.time()
# percent.995 <- perc_0_995(proyeccion_data)
# proc.time()-t

Guardar las proyecciones

# write_xlsx(media, "res/media.xlsx")
# write_xlsx(percent.995, "res/percentil.xlsx")

Leer las proyecciones

media <- list(
  read_xlsx("res/media.xlsx", sheet = 1),
  read_xlsx("res/media.xlsx", sheet = 2),
  read_xlsx("res/media.xlsx", sheet = 3),
  read_xlsx("res/media.xlsx", sheet = 4)
)
percent.995 <- list(
  read_xlsx("res/percentil.xlsx", sheet = 1),
  read_xlsx("res/percentil.xlsx", sheet = 2),
  read_xlsx("res/percentil.xlsx", sheet = 3),
  read_xlsx("res/percentil.xlsx", sheet = 4)
)

Gráficos

Ingresos y egresos

sum(media[[3]][[1]])
## [1] 10502128064
sum(media[[3]][[2]])
## [1] 9262581939
sum(media[[4]][[1]])
## [1] 11187690601
sum(media[[4]][[2]])
## [1] 11600273306
sum(percent.995[[3]][[1]])
## [1] 10715653825
sum(percent.995[[3]][[2]])
## [1] 8132304125
sum(percent.995[[4]][[1]])
## [1] 11394721399
sum(percent.995[[4]][[2]])
## [1] 10446976695